﻿////****************************************************************************
////
//// Descriptive Name = A  data access wrapper library for IBM.Data.DB2.iSeries
//// provider.
//// Short Name = ISeriesDataProxy
//// Function = A data access proxy for client applications. 
////
//// Copyright for IBM.Data.DB2.iSeries and other IBM libraries used belongs to 
//// IBM Corp 2008
////
////****************************************************************************
////============================================================================
//// Copyright © Shibu Raj - shibukraj@gmail.com.  All Rights Reserved.
//// This code released under the terms of the 
//// GNU General Public License version 2 (GPLv2) 
//// (http://isereisdataproxy.codeplex.com/license)
////============================================================================

namespace ISeriesDataProxyTest
{
    using System;
    using System.Data;
    using System.Data.Common;
    
    using System.Xml;
    using IBM.Data.DB2.iSeries;
    using ISeriesDataProxy;
    using Moq;
    using NUnit.Framework;

    /// <summary>
    /// Unit test class for Db2Database class.
    /// </summary>
    [TestFixture]
    public class Db2DatabaseTest
    {
        private string connectionString = @"DataSource=NASDEV; UserID=ADMINLARC; Password=LARC0802; SSL=false; ConnectionTimeout=60; DataCompression=true; Naming=System; MaximumPoolSize=500; MinimumPoolSize=10; CheckConnectionOnOpen=true; MaximumUseCount=100; Trace=StartDebug,PrintJobLog; Pooling=true;";

        //// private string connectionString = @"DataSource=NASDEV; UserID=ADMINLARC; Password=LARC0802; SSL=false; ConnectionTimeout=60;  Database=myDB; DataCompression=true; Naming=System; DefaultCollection=myDatabase; LibraryList=SCHEMA1, SCHEMA2, *USRLIBL; MaximumPoolSize=500; MinimumPoolSize=500; CheckConnectionOnOpen=true; MaximumUseCount=100; DataCompression=True;  Trace=TraceJob, StartDebug,PrintJobLog; Pooling=true;";

        /// <summary>
        /// Test the Db2Database constructor with a valid connection string.
        /// </summary>
        [Test]
        public void Db2DatabaseConstructorWithValidConnectionStringTest()
        {
            ////Arrange            
            Db2Database database;
            ////Act 
            database = new Db2Database(this.connectionString);
            ////Assert            
            Assert.IsNotNull(database, "Default Constructor test completed sucessfully");
        }

        [Test]
        public void Db2DatabaseConstructorWithNoConnectionStringTest()
        {
            //// Arrange
            string connectionString_bad = string.Empty;
            //// Act
            Db2Database database;
            //// Assert
            Assert.Throws(typeof(ArgumentException), delegate
            {
                database = new Db2Database(connectionString_bad);
            });
        }

        [Test]
        public void AddParameterTest()
        {
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command = new iDB2Command();
            //// Act
            database.AddInParameter(
                command, "Parameter1", System.Data.DbType.String, "Coloumn1",
                System.Data.DataRowVersion.Default);
            //// Assert
            Assert.AreEqual(command.CommandText, string.Empty);
            Assert.AreEqual(command.Parameters.Count, 1);
            Assert.AreEqual(command.Parameters[0].ParameterName, "Parameter1");
            Assert.AreEqual(command.Parameters[0].DbType, System.Data.DbType.String);
            Assert.AreEqual(command.Parameters[0].SourceColumn, "Coloumn1");
            Assert.AreEqual(command.Parameters[0].SourceVersion, System.Data.DataRowVersion.Default);
        }

        [Test]
        public void SetParameterValueTest()
        {
            ///// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command = new iDB2Command();
            iDB2Parameter parameter = new iDB2Parameter();
            parameter.ParameterName = "Parameter1";
            command.Parameters.Add(parameter);
            //// Act
            database.SetParameterValue(command, "Parameter1", "value1");
            //// Assert
            Assert.IsTrue(command.Parameters[0].Value.Equals("value1"));
        }

        [Test]
        public void CreateConnectionTest()
        {
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            //// Act
            DbConnection conn = database.CreateConnection();
            //// Assert
            Assert.IsNotNull(conn);
            Assert.IsTrue(conn.State == System.Data.ConnectionState.Closed);
            Assert.IsTrue(conn.DataSource.Equals("NASDEV"));
            Assert.IsTrue(conn.ConnectionTimeout == 60);
            //// Act
            conn.Open();
            //// Assert
            Assert.IsTrue(conn.State == System.Data.ConnectionState.Open);
            //// Clean up 
            conn.Close();
            conn.Dispose();
        }

        [Test]
        public void GetStoredProcCommandWithParameterArrayTest()
        {
            ///// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            //// Act            
            iDB2Command command = (iDB2Command)database.GetStoredProcCommand("DISR0277W", "LAPD", "1234567", "SRAJ", "111111");
            //// Assert
            Assert.IsTrue(command.Parameters.Count == 4);
            Assert.AreSame(command.Parameters[0].Value.ToString(), "LAPD");
            Assert.AreSame(command.Parameters[1].Value.ToString(), "1234567");
            Assert.AreSame(command.Parameters[2].Value.ToString(), "SRAJ");
            Assert.AreSame(command.Parameters[3].Value.ToString(), "111111");
        }

        [Test]
        public void GetStoredProcCommandWithNoParametersTest()
        {
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command;
            //// Act
            command = (iDB2Command)database.GetStoredProcCommand("DISR0277W");
            //// Assert
            Assert.IsNotNull(command);
            Assert.IsTrue(command.Parameters.Count == 0);
        }

        [Test]
        public void GetStoredProcCommandWithSourceColumnsTest()
        {
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command;
            //// Act            
            //// Assert
            Assert.Throws<ArgumentNullException>(delegate { database.GetStoredProcCommandWithSourceColumns("DISR0277W", null); });
            string[] coloumns = new string[0];

            Assert.Throws<ArgumentException>(delegate { database.GetStoredProcCommandWithSourceColumns("DISR0277W", coloumns); });
            string[] coloumn_data = new string[4];
            coloumn_data[0] = "PREFIX";
            coloumn_data[1] = "SEQUENCE#";
            coloumn_data[2] = "FNAME";
            coloumn_data[3] = "DOB";
            command = (iDB2Command)database.GetStoredProcCommandWithSourceColumns("DISR0277W", coloumn_data);            
            Assert.NotNull(command);
            /// TODO - This test is not fully covered. This needs to be changed. 
        }

        [Test]
        public void GetSqlStringCommandTest()
        { 
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            string sqlText = "SELECT * FROM DIRERTRN";
            iDB2Command command;
            //// Act
            command = (iDB2Command) database.GetSqlStringCommand(sqlText);
            //// Assert
            Assert.NotNull(command);
        }

        [Test]
        public void GetParameterValueTest()
        { 
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command = new iDB2Command();
            database.AddParameter(command, "TestParam", DbType.String, ParameterDirection.Input, "TestColoumn", DataRowVersion.Default, "TestValue");
            //// Act
            object paramValue = database.GetParameterValue(command, "TestParam");
            //// Assert
            Assert.IsTrue(paramValue.ToString() == "TestValue");
        }
        
        [Test]
        public void DiscoverParametersTest()
        {
            ///// Arrange 
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command = (iDB2Command)database.GetStoredProcCommand("DISR0277W");
            //// Act
            database.DiscoverParameters(command);
            //// Assert
            Assert.IsTrue(command.Parameters.Count == 4);
            Assert.IsTrue(command.Parameters[0].ParameterName == "PREFIX");
            Assert.IsTrue(command.Parameters[1].ParameterName == "SEQUENCE#");
            Assert.IsTrue(command.Parameters[2].ParameterName == "FNAME");
            Assert.IsTrue(command.Parameters[3].ParameterName == "DOB");
        }

        [Test]
        public void ExecuteNonQueryTest()
        { 
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            string sqlText_Select = "Select count(*) from DIRERTRN";
            iDB2Command command = (iDB2Command) database.GetSqlStringCommand(sqlText_Select);
            //// Act
            int retValue = database.ExecuteNonQuery(command);
            //// Assert
            Assert.AreEqual(-1, retValue); // Select statement return -1.
            command.Dispose();
            //// Arrange
            String sqlText_Update = "Update DIRERTRN SET RTIMSG = '{0}' Where RTRQID = '{1}'";
            command = (iDB2Command)database.GetSqlStringCommand(string.Format(sqlText_Update, "THIS IS TEST 2", "08111317316135002:WPCLB0000003780"));
            //// Act
            retValue = database.ExecuteNonQuery(command);
            //// Assert
            Assert.AreEqual(1,retValue);
            command.Dispose();
            /// Arrange
            command = (iDB2Command)database.GetSqlStringCommand(string.Format(sqlText_Update, "THIS IS TEST 2", "08111317316135002:CLB0000003780"));
            //// Act
            retValue = database.ExecuteNonQuery(command);
            //// Assert
            Assert.AreEqual(0, retValue);
            command.Dispose();                      
        }

        [Test]
        public void ExecuteNonQueryUnderTransactionTest()
        { 
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            string sqlText_update = "Update DIRERTRN SET RTIMSG = '{0}' Where RTRQID = '{1}'";
            iDB2Connection conn = (iDB2Connection) database.CreateConnection();
            conn.Open();
            iDB2Transaction trans = conn.BeginTransaction();            
            iDB2Command command = (iDB2Command)database.GetSqlStringCommand(string.Format(sqlText_update, "TEST ROLLBACK", ""));
            int retVal = database.ExecuteNonQuery(command, trans);
            Assert.AreEqual(2, retVal);
            command = (iDB2Command)database.GetSqlStringCommand(string.Format(sqlText_update, "TEST ROLLBACK", ""));
            retVal = database.ExecuteNonQuery(command, trans);
            Assert.AreEqual(2, retVal);
            trans.Rollback();           
        }

        [Test]
        public void LoadDatasetTest()
        {
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            iDB2Command command = (iDB2Command)database.GetSqlStringCommand(@"SELECT * FROM DIRERTRN");
            DataSet ds = new DataSet();
            //// Act
            database.LoadDataSet(command, ds, "DIREPT");
            ///// Assert
            Assert.IsNotNull(ds.Tables);
        }

        [Test]
        public void ExecuteDatasetTest()
        { 
            //// Arrange
            Db2Database database = new Db2Database(this.connectionString);
            //// Act
            iDB2Command command = (iDB2Command)database.GetSqlStringCommand(@"SELECT * FROM DIRERTRN");
            //// Assert
            DataSet ds = database.ExecuteDataSet(command);
            Assert.IsNotNull(ds);
        }
    }
}
